home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 2 / Atari Mega Archive CD - Volume 2.iso / minix / up1510b.tgz / up1510b / src / commands / od.c < prev    next >
C/C++ Source or Header  |  1990-07-23  |  5KB  |  325 lines

  1. /* od - octal dump           Author: Andy Tanenbaum */
  2.  
  3. #include <sys/types.h>
  4. #include <fcntl.h>
  5. #include <unistd.h>
  6. #include <stdio.h>
  7.  
  8.  
  9. int bflag, cflag, dflag, oflag, xflag, hflag, linenr, width, state, ever;
  10. int prevwds[8];
  11. long off;
  12. char buf[512], buffer[BUFSIZ];
  13. int next;
  14. int bytespresent;
  15. char hexit();
  16.  
  17. main(argc, argv)
  18. int argc;
  19. char *argv[];
  20. {
  21.   int k, flags;
  22.   long offset();
  23.   char *p;
  24.  
  25.   /* Process flags */
  26.   setbuf(stdout, buffer);
  27.   flags = 0;
  28.   p = argv[1];
  29.   if (argc > 1 && *p == '-') {
  30.     /* Flags present. */
  31.     flags++;
  32.     p++;
  33.     while (*p) {
  34.         switch (*p) {
  35.             case 'b':    bflag++;    break;
  36.             case 'c':    cflag++;    break;
  37.             case 'd':    dflag++;    break;
  38.             case 'h':    hflag++;    break;
  39.             case 'o':    oflag++;    break;
  40.             case 'x':    xflag++;    break;
  41.             default:    usage();
  42.         }
  43.         p++;
  44.     }
  45.   } else {
  46.     oflag = 1;
  47.   }
  48.   if ((bflag | cflag | dflag | oflag | xflag) == 0) oflag = 1;
  49.   k = (flags ? 2 : 1);
  50.   if (bflag | cflag) {
  51.     width = 8;
  52.   } else if (oflag) {
  53.     width = 7;
  54.   } else if (dflag) {
  55.     width = 6;
  56.   } else {
  57.     width = 5;
  58.   }
  59.  
  60.   /* Process file name, if any. */
  61.   p = argv[k];
  62.   if (k < argc && *p != '+') {
  63.     /* Explicit file name given. */
  64.     close(0);
  65.     if (open(argv[k], O_RDONLY) != 0) {
  66.         std_err("od: cannot open ");
  67.         std_err(argv[k]);
  68.         std_err("\n");
  69.         exit(1);
  70.     }
  71.     k++;
  72.   }
  73.  
  74.   /* Process offset, if any. */
  75.   if (k < argc) {
  76.     /* Offset present. */
  77.     off = offset(argc, argv, k);
  78.     off = (off / 16L) * 16L;
  79.     lseek(0, off, SEEK_SET);
  80.   }
  81.   dumpfile();
  82.   addrout(off);
  83.   printf("\n");
  84.   exit(0);
  85. }
  86.  
  87.  
  88. long offset(argc, argv, k)
  89. int argc;
  90. char *argv[];
  91. int k;
  92. {
  93.   int dot, radix;
  94.   char str[80], *p, c;
  95.   long val;
  96.  
  97.   /* See if the offset is decimal. */
  98.   dot = 0;
  99.   p = argv[k];
  100.   while (*p)
  101.     if (*p++ == '.') dot = 1;
  102.  
  103.   /* Convert offset to binary. */
  104.   radix = (dot ? 10 : 8);
  105.   val = 0;
  106.   p = argv[k];
  107.   if (*p == '+') p++;
  108.   while (*p != 0 && *p != '.') {
  109.     c = *p++;
  110.     if (c < '0' || c > '9') {
  111.         printf("Bad character in offset: %c\n", c);
  112.         exit(1);
  113.     }
  114.     val = radix * val + c - '0';
  115.   }
  116.  
  117.   p = argv[k + 1];
  118.   if (k + 1 == argc - 1 && *p == 'b') val = 512L * val;
  119.   return(val);
  120. }
  121.  
  122.  
  123. dumpfile()
  124. {
  125.   int k;
  126.   short *words;
  127.  
  128.   while ((k = getwords(&words))) {    /* 'k' is # bytes read */
  129.     if (k == 16 && same(words, prevwds) && ever == 1) {
  130.         if (state == 0) {
  131.             printf("*\n");
  132.             state = 1;
  133.             off += 16;
  134.             continue;
  135.         } else if (state == 1) {
  136.             off += 16;
  137.             continue;
  138.         }
  139.     }
  140.     addrout(off);
  141.     off += k;
  142.     state = 0;
  143.     ever = 1;
  144.     linenr = 1;
  145.     if (oflag) wdump(words, k, 8);
  146.     if (dflag) wdump(words, k, 10);
  147.     if (xflag) wdump(words, k, 16);
  148.     if (cflag) bdump(words, k, 'c');
  149.     if (bflag) bdump(words, k, 'b');
  150.     for (k = 0; k < 8; k++) prevwds[k] = words[k];
  151.     for (k = 0; k < 8; k++) words[k] = 0;
  152.   }
  153. }
  154.  
  155.  
  156. wdump(words, k, radix)
  157. short *words;
  158. int k, radix;
  159. {
  160.   int i;
  161.  
  162.   if (linenr++ != 1) printf("       ");
  163.   for (i = 0; i < (k + 1) / 2; i++) outword(words[i], radix);
  164.   printf("\n");
  165. }
  166.  
  167.  
  168. bdump(bytes, k, c)
  169. char bytes[16];
  170. int k;
  171. char c;
  172. {
  173.   int i;
  174.  
  175.   if (linenr++ != 1) printf("       ");
  176.   for (i = 0; i < k; i++) byte(bytes[i] & 0377, c);
  177.   printf("\n");
  178. }
  179.  
  180. byte(val, c)
  181. int val;
  182. char c;
  183. {
  184.   if (c == 'b') {
  185.     printf(" ");
  186.     outnum(val, 7);
  187.     return;
  188.   }
  189.   if (val == 0)
  190.     printf("  \\0");
  191.   else if (val == '\b')
  192.     printf("  \\b");
  193.   else if (val == '\f')
  194.     printf("  \\f");
  195.   else if (val == '\n')
  196.     printf("  \\n");
  197.   else if (val == '\r')
  198.     printf("  \\r");
  199.   else if (val == '\t')
  200.     printf("  \\t");
  201.   else if (val >= ' ' && val < 0177)
  202.     printf("   %c", val);
  203.   else {
  204.     printf(" ");
  205.     outnum(val, 7);
  206.   }
  207. }
  208.  
  209.  
  210. int getwords(words)
  211. short **words;
  212. {
  213.   int count;
  214.  
  215.   if (next >= bytespresent) {
  216.     bytespresent = read(0, buf, 512);
  217.     next = 0;
  218.   }
  219.   if (next >= bytespresent) return(0);
  220.   *words = (short *) &buf[next];
  221.   if (next + 16 <= bytespresent)
  222.     count = 16;
  223.   else
  224.     count = bytespresent - next;
  225.  
  226.   next += count;
  227.   return(count);
  228. }
  229.  
  230. int same(w1, w2)
  231. short *w1;
  232. int *w2;
  233. {
  234.   int i;
  235.   i = 8;
  236.   while (i--)
  237.     if (*w1++ != *w2++) return(0);
  238.   return(1);
  239. }
  240.  
  241. outword(val, radix)
  242. int val, radix;
  243. {
  244. /* Output 'val' in 'radix' in a field of total size 'width'. */
  245.  
  246.   int i;
  247.  
  248.   if (radix == 16) i = width - 4;
  249.   if (radix == 10) i = width - 5;
  250.   if (radix == 8) i = width - 6;
  251.   if (i == 1)
  252.     printf(" ");
  253.   else if (i == 2)
  254.     printf("  ");
  255.   else if (i == 3)
  256.     printf("   ");
  257.   else if (i == 4)
  258.     printf("    ");
  259.   outnum(val, radix);
  260. }
  261.  
  262.  
  263. outnum(num, radix)
  264. int num, radix;
  265. {
  266. /* Output a number with all leading 0s present.  Octal is 6 places,
  267.  * decimal is 5 places, hex is 4 places.
  268.  */
  269.   int d, i;
  270.   unsigned val;
  271.   char s[8];
  272.  
  273.   val = (unsigned) num;
  274.   if (radix == 8)
  275.     d = 6;
  276.   else if (radix == 10)
  277.     d = 5;
  278.   else if (radix == 16)
  279.     d = 4;
  280.   else if (radix == 7) {
  281.     d = 3;
  282.     radix = 8;
  283.   }
  284.   for (i = 0; i < d; i++) {
  285.     s[i] = val % radix;
  286.     val -= s[i];
  287.     val = val / radix;
  288.   }
  289.   for (i = d - 1; i >= 0; i--) {
  290.     if (s[i] > 9)
  291.         printf("%c", 'a' + s[i] - 10);
  292.     else
  293.         printf("%c", s[i] + '0');
  294.   }
  295. }
  296.  
  297.  
  298. addrout(l)
  299. long l;
  300. {
  301.   int i;
  302.  
  303.   if (hflag == 0) {
  304.     for (i = 0; i < 7; i++)
  305.         printf("%c", (int) ((l >> (18 - 3 * i)) & 07) + '0');
  306.   } else {
  307.     for (i = 0; i < 7; i++)
  308.         printf("%c", hexit((int) ((l >> (24 - 4 * i)) & 0x0F)));
  309.   }
  310. }
  311.  
  312. char hexit(k)
  313. int k;
  314. {
  315.   if (k <= 9)
  316.     return('0' + k);
  317.   else
  318.     return('A' + k - 10);
  319. }
  320.  
  321. usage()
  322. {
  323.   std_err("Usage: od [-bcdhox] [file] [ [+] offset [.] [b] ]");
  324. }
  325.